home *** CD-ROM | disk | FTP | other *** search
/ Suzy B Software 2 / Suzy B Software CD-ROM 2 (1994).iso / prntutil / ascreen / fontlist / fontlist.c next >
C/C++ Source or Header  |  1995-04-25  |  5KB  |  211 lines

  1. /* FONTLIST --- in einem TeX-Dokument benutzte Zeichens"atze auflisten
  2. ** Copyright (C) 1992 by Anselm Lingnau
  3. **
  4. ** Sie d"urfen dieses Programm frei verwenden und weitergeben, solange
  5. ** Sie kein Geld damit verdienen oder behaupten, Sie h"atten es
  6. ** geschrieben.
  7. **
  8. ** Dieses Programm ist `fast' ISO-C-konform, es hat nur eine unportable
  9. ** Stelle: eine Implementierung muss fseek(..., ..., SEEK_END) auf
  10. ** Bin"ardateien nicht sinnvoll unterst"utzen. Eine Abhilfe besteht
  11. ** in schlimmen Notf"allen darin, die Datei komplett zu lesen und dabei
  12. ** die Bytes zu z"ahlen (die einzige portable M"oglichkeit, die L"ange
  13. ** einer Datei herauszufinden) und dann fseek(..., laenge, SEEK_SET)
  14. ** zu sagen. W"urg.
  15. */
  16. #include <stdio.h>
  17. #include <stdlib.h>
  18. #include <string.h>
  19.  
  20. #define DVI_ID        2
  21. #define FNT_DEF1    243
  22. #define FNT_DEF4    246
  23.  
  24. #define MAX_FONT_NAME    511
  25.  
  26. char *prog_name;
  27.  
  28. char *fmt = "%F %M", *res = "101", *ext = "scr", *outf = NULL;
  29.  
  30. FILE *out = stdout;
  31.  
  32.     void
  33. usage (void)
  34. {
  35.     fputs("FONTLIST --- Auflisten der Zeichens\"atze in einer DVI-Datei\n"
  36.         "Copyright (C) 1992 by Anselm Lingnau\n\n"
  37.         "Gebrauch: fontlist [Optionen] Datei\n\n"
  38.     "Optionen: -l         Liste im Lindner-Stil\n"
  39.     "          -s         Liste im Strunk-Stil\n"
  40.     "          -f<Format> Liste im angegebenen Format; dabei ist\n"
  41.     "                     %F - Zeichensatzname\n"
  42.         "                     %R - Aufl\"osung (aus -r-Option)\n"
  43.     "                     %M - Vergr\"osserung (Fliesskomma)\n", stderr);
  44.     fputs("                     %m - Vergr\"osserung (Ganzzahl)\n"
  45.     "                     %E - Ger\"ate-Endung (aus -e-Option)\n"
  46.     "          -e<Endung> f\"ur %E im Format\n"
  47.     "          -r<Zahl>   f\"ur %R im Format\n"
  48.     "          -m<Zahl>   Vergr\"osserung\n"
  49.     "          -o<Datei>  Name der Ausgabedatei (sonst stdout)\n\n"
  50.     "Beispiel:\n"
  51.     "          Lindner-Stil ist: -escr -r101 -f\"res%R.%E %M %F\"\n"
  52.     "\n", stderr);
  53. }
  54.  
  55.     unsigned long
  56. get_quad (FILE *f)
  57. {
  58.     unsigned long q = 0;
  59.     q = (unsigned long)getc(f);
  60.     q = 256 * q + (unsigned long)getc(f);
  61.     q = 256 * q + (unsigned long)getc(f);
  62.     return 256 * q + (unsigned long)getc(f);
  63. }
  64.  
  65.     int
  66. safer_seeks (FILE *f, long offset, int whence)
  67. {
  68.     if (fseek(f, offset, whence) != 0) {
  69.         fprintf(stderr, "%s: konnte nicht positionieren\n",
  70.             prog_name);
  71.         return 0;
  72.     }
  73.     return 1;
  74. }
  75.  
  76.     int
  77. find_postamble (FILE *f)
  78. {
  79.     int i, done;
  80.     unsigned long post;
  81.  
  82.     if (safer_seeks(f, -1L, SEEK_END) == 0) return 0;
  83.     done = 0;
  84.     while (!done) {
  85.         if ((i = getc(f)) == EOF) {
  86.             fprintf(stderr, "%s: Lesefehler!\n", prog_name);
  87.             return 0;
  88.         }
  89.         if (i == DVI_ID)
  90.             done = 1;
  91.         else if (safer_seeks(f, -2L, SEEK_CUR) == 0)
  92.             return 0;
  93.     }
  94.     if (safer_seeks(f, -5L, SEEK_CUR) == 0)
  95.         return 0;
  96.     post = get_quad(f);
  97.     return safer_seeks(f, post, SEEK_SET);
  98. }
  99.  
  100.     int
  101. read_font_def (FILE *f, unsigned long mag)
  102. {
  103.     int op, i, len;
  104.     unsigned long s, d;
  105.     char name[MAX_FONT_NAME], *p;
  106.  
  107.     op = (unsigned int)getc(f);
  108.     if (op < FNT_DEF1 || op > FNT_DEF4)
  109.         return 0;
  110.     for (i = op - FNT_DEF1 + 1; i > 0; --i)
  111.         (void)getc(f);
  112.     (void)get_quad(f);        /* Pr"ufsumme */
  113.     s = get_quad(f);
  114.     d = get_quad(f);
  115.     len = (unsigned int)getc(f);
  116.     len += (unsigned int)getc(f);
  117.     for (i = 0; i < len; ++i)
  118.         name[i] = getc(f);
  119.     name[i] = '\0';
  120.     for (p = fmt; *p; ++p) {
  121.         if (*p == '%')
  122.         switch (*++p) {
  123.             case 'R':
  124.                 fprintf(out, "%s", res); break;
  125.             case 'E':
  126.                 fprintf(out, "%s", ext); break;
  127.             case 'M':
  128.                 fprintf(out, "%5.3f", (double)mag * s / 1000.0 / d);
  129.             break;
  130.             case 'm':
  131.                 fprintf(out, "%d", (int)((double)mag * s / d));
  132.             break;
  133.             case 'F': 
  134.             fputs(name, out);
  135.             break;
  136.             case '%':
  137.             putc('%', out);
  138.             break;
  139.             default:
  140.             fprintf(stderr, "%s: Ung\"ultiges Format %%%c\n",
  141.                 prog_name, *p);
  142.         }
  143.         else
  144.             putc(*p, out);
  145.     }
  146.     putc('\n', out);
  147.     return 1;
  148. }
  149.  
  150.     int
  151. fontlist (const char *file, unsigned long umag)
  152. {
  153.     unsigned long mag;
  154.     FILE *f = fopen(file, "rb");
  155.  
  156.     if (f == NULL) {
  157.         fprintf(stderr, "%s: konnte %s nicht \"offnen\n",
  158.             prog_name, file);
  159.         return 0;
  160.     }
  161.     if (!find_postamble(f)) {
  162.         fprintf(stderr, "%s: konnte Postambel in %s nicht finden\n",
  163.             prog_name, file);
  164.         return 0;
  165.     }
  166.     if (safer_seeks(f, 13L, SEEK_CUR) == 0)
  167.         return 0;
  168.     mag = get_quad(f);
  169.     if (umag) mag = umag;
  170.     if (safer_seeks(f, 12L, SEEK_CUR) == 0)
  171.         return 0;
  172.     while (read_font_def(f, mag))
  173.         ;
  174.     (void)fclose(f);
  175.     return 1;
  176. }
  177.  
  178.     int
  179. main (int argc, char **argv)
  180. {
  181.     unsigned long umag = 0;
  182.  
  183.     prog_name = *argv;
  184.     if (argc <= 1) {
  185.         usage();
  186.         return EXIT_FAILURE;
  187.     }
  188.     while (**++argv == '-') {
  189.         switch (*(*argv + 1)) {
  190.         case 'e': ext = *argv + 2; break;
  191.         case 'r': res = *argv + 2; break;
  192.         case 'f': fmt = *argv + 2; break;
  193.         case 'l': fmt = "res%R.%E %F %M"; break;
  194.         case 'm': umag = strtoul(*argv + 2, (char **)NULL, 0); break;
  195.         case 'o': outf = *argv + 2;
  196.         case 's': fmt = "%F in magnification %m"; break;
  197.         default: usage(); return EXIT_FAILURE;
  198.         }
  199.     }
  200.     if (*argv == NULL) {
  201.         usage();
  202.         return EXIT_FAILURE;
  203.     }
  204.     if (outf && (out = fopen(outf, "w")) == NULL) {
  205.         fprintf(stderr, "%s: konnte %s nicht \"offnen\n",
  206.             prog_name, outf);
  207.         return EXIT_FAILURE;
  208.     }
  209.     return fontlist(*argv, umag) ? EXIT_SUCCESS : EXIT_FAILURE;
  210. }
  211.